package com.ruoyi.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.ruoyi.common.core.controller.BaseController;

/**
 * 图片下载控制器
 * 
 * @author ruoyi
 */
@Controller
@RequestMapping("/download")
@CrossOrigin(origins = "*", maxAge = 3600)
public class ImageDownloadController extends BaseController {
    
    private static final Logger log = LoggerFactory.getLogger(ImageDownloadController.class);
    
    // 允许的域名列表
    private static final List<String> VALID_DOMAINS = Arrays.asList("ad.ktmjk.com", "localhost", "127.0.0.1", "v.zhnfad.com");
    
    /**
     * 图片下载处理
     */
    @GetMapping("/image")
    public void downloadImage(HttpServletRequest request, HttpServletResponse response) {
        String fileUrl = request.getParameter("url");
        String fileName = request.getParameter("filename");
        String autoDownload = request.getParameter("autodownload");
        boolean isAutoDownload = "true".equalsIgnoreCase(autoDownload);
        
        if (fileUrl == null || fileUrl.isEmpty()) {
            sendErrorResponse(response, HttpServletResponse.SC_BAD_REQUEST, "URL参数不能为空");
            return;
        }
        
        if (fileName == null || fileName.isEmpty()) {
            fileName = "image"; // 默认文件名
        }
        
        try {
            // URL解码处理，解决多次编码问题
            fileUrl = URLDecoder.decode(fileUrl, "UTF-8");
            
            // 针对特殊情况，如果URL包含%，可能需要再次解码
            if (fileUrl.contains("%")) {
                try {
                    String testDecodedUrl = URLDecoder.decode(fileUrl, "UTF-8");
                    if (testDecodedUrl.startsWith("http")) {
                        fileUrl = testDecodedUrl;
                    }
                } catch (Exception e) {
                    // 如果二次解码失败，保留原解码结果
                    log.warn("二次URL解码失败", e);
                }
            }
            
            log.info("处理下载请求: {}", fileUrl);

            URL url = new URL(fileUrl);
            String host = url.getHost();
            boolean validDomain = false;
            
            for (String domain : VALID_DOMAINS) {
                if (host.endsWith(domain)) {
                    validDomain = true;
                    break;
                }
            }
            
            if (!validDomain) {
                log.error("请求的域名不在允许列表中: {}", host);
                sendErrorResponse(response, HttpServletResponse.SC_FORBIDDEN, "禁止访问该域名");
                return;
            }
            
            // 设置CORS和安全头
            response.setHeader("Content-Security-Policy", "default-src 'self'");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept");
            
            // HTTP/HTTPS处理
            if (fileUrl.startsWith("http:") && request.isSecure()) {
                // 如果后端是HTTPS但请求的URL是HTTP，尝试将URL转换为HTTPS
                fileUrl = fileUrl.replace("http:", "https:");
                log.info("将图片URL从HTTP转换为HTTPS: {}", fileUrl);
                url = new URL(fileUrl);
            }
            
            // 处理远程URL
            HttpURLConnection connection;
            try {
                if (url.getProtocol().equals("https")) {
                    connection = (HttpURLConnection) url.openConnection();
                    ((javax.net.ssl.HttpsURLConnection) connection).setHostnameVerifier((hostname, session) -> true);
                } else {
                    connection = (HttpURLConnection) url.openConnection();
                }
                
                connection.setRequestMethod("GET");
                connection.setRequestProperty("User-Agent", "Mozilla/5.0");
                connection.setRequestProperty("Accept", "image/*");
                
                // 添加Referer，避免某些服务器的防盗链限制
                String referer = request.getHeader("Referer");
                if (referer != null && !referer.isEmpty()) {
                    connection.setRequestProperty("Referer", referer);
                } else {
                    connection.setRequestProperty("Referer", url.getProtocol() + "://" + url.getHost());
                }
                
                connection.setConnectTimeout(15000);
                connection.setReadTimeout(15000);
                connection.setInstanceFollowRedirects(true);
                
                int responseCode = connection.getResponseCode();
                if (responseCode != HttpURLConnection.HTTP_OK) {
                    log.error("下载图片失败，HTTP状态码: {}, URL: {}", responseCode, fileUrl);
                    sendErrorResponse(response, responseCode, "下载图片失败，服务器返回: " + responseCode);
                    return;
                }
                
                String contentType = connection.getContentType();
                if (contentType == null || contentType.isEmpty()) {
                    contentType = "image/jpeg";
                }
                
                // 确定文件扩展名
                String extension = ".jpg";
                if (contentType.contains("png")) {
                    extension = ".png";
                } else if (contentType.contains("gif")) {
                    extension = ".gif";
                } else if (contentType.contains("webp")) {
                    extension = ".webp";
                }
                
                // 设置响应头
                response.setContentType(contentType);
                
                // 获取内容长度
                int contentLength = connection.getContentLength();
                if (contentLength > 0) {
                    response.setContentLength(contentLength);
                }
                
                // 设置下载文件名
                String disposition = isAutoDownload ? 
                        "attachment; filename=\"" + URLEncoder.encode(fileName + extension, "UTF-8") + "\"" : 
                        "inline; filename=\"" + URLEncoder.encode(fileName + extension, "UTF-8") + "\"";
                response.setHeader("Content-Disposition", disposition);
                
                // 将图片内容写入响应
                try (InputStream in = connection.getInputStream();
                     OutputStream out = response.getOutputStream()) {
                    byte[] buffer = new byte[8192]; // 使用更大的缓冲区
                    int bytesRead;
                    while ((bytesRead = in.read(buffer)) != -1) {
                        out.write(buffer, 0, bytesRead);
                    }
                }
                
                log.info("图片下载成功: {}, 下载方式: {}", fileName + extension, isAutoDownload ? "自动下载" : "手动下载");
            } catch (Exception e) {
                log.error("连接远程服务器失败", e);
                sendErrorResponse(response, HttpServletResponse.SC_BAD_GATEWAY, "无法连接到图片服务器: " + e.getMessage());
            }
        } catch (Exception e) {
            log.error("下载过程中发生错误", e);
            sendErrorResponse(response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器内部错误: " + e.getMessage());
        }
    }
    
    /**
     * 发送错误响应
     */
    private void sendErrorResponse(HttpServletResponse response, int status, String message) {
        try {
            response.setStatus(status);
            response.setContentType("text/plain;charset=UTF-8");
            response.getWriter().write(message);
        } catch (IOException e) {
            log.error("发送错误响应失败", e);
        }
    }
} 